package com.labi.designpattern.config;

import com.labi.designpattern.action.OrderAction;
import com.labi.designpattern.database.MockDB;
import com.labi.designpattern.entity.OrderEntity;
import com.labi.designpattern.enums.OrderEvent;
import com.labi.designpattern.enums.OrderState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.statemachine.StateMachine;
import org.springframework.statemachine.StateMachineContext;
import org.springframework.statemachine.StateMachinePersist;
import org.springframework.statemachine.config.EnableStateMachine;
import org.springframework.statemachine.config.StateMachineConfigurerAdapter;
import org.springframework.statemachine.config.StateMachineFactory;
import org.springframework.statemachine.config.builders.StateMachineStateBuilder;
import org.springframework.statemachine.config.builders.StateMachineStateConfigurer;
import org.springframework.statemachine.config.builders.StateMachineTransitionConfigurer;
import org.springframework.statemachine.persist.DefaultStateMachinePersister;
import org.springframework.statemachine.persist.StateMachinePersister;
import org.springframework.statemachine.state.State;
import org.springframework.statemachine.support.DefaultStateMachineContext;

import java.util.EnumSet;

@Configuration // 标识这个类是一个Spring配置类
//@EnableStateMachine // 启用Spring State Machine的功能
@EnableStateMachine(name = "orderStateMachine")
public class OrderStateMachineConfig extends StateMachineConfigurerAdapter<OrderState, OrderEvent> {

    @Autowired
    OrderAction orderAction;
    // 配置状态机状态
    @Override
    public void configure(StateMachineStateConfigurer<OrderState, OrderEvent> states) throws Exception {
        states
                // 定义CREATED状态
                .withStates()
                .initial(OrderState.CREATED)
                .states(EnumSet.allOf(OrderState.class)); // 设置CREATED为初始状态

    }

//    // 创建状态构建器，可以添加更多配置（如子状态、进入/退出动作等）
//    private State<OrderState, String> createStateBuilder(OrderState state) {
//        return new StateMachineStateBuilder<OrderState, String>(state)
//                .build();
//    }

    // 配置状态机转换
    @Override
    public void configure(StateMachineTransitionConfigurer<OrderState, OrderEvent> transitions) throws Exception {
        transitions
                .withExternal()
                .source(OrderState.CREATED).target(OrderState.WAIT_CHECKED).event(OrderEvent.CHECK_EVENT)
                .action(orderAction.checkAction())
                .and()
                .withExternal()
                .source(OrderState.WAIT_CHECKED).target(OrderState.PAID).event(OrderEvent.PAY_EVENT)
                .and()
                .withExternal()
                .source(OrderState.PAID).target(OrderState.COMPLETED).event(OrderEvent.WRITEBACK_EVENT);
    }

    // 创建状态机的Bean
//    @Bean(name = "orderStateMachine")
//    public StateMachine<OrderState, OrderEvent> orderStateMachine(StateMachineFactory<OrderState, OrderEvent> factory) throws Exception {
//        return factory.getStateMachine("orderStateMachine");
//    }

    // 可以添加更多配置方法，例如监听器配置、守卫配置等

    @Bean
    public StateMachinePersister<OrderState, OrderEvent, String> persister(){
        return new DefaultStateMachinePersister<>(new StateMachinePersist<OrderState, OrderEvent, String>() {
            @Override
            public void write(StateMachineContext<OrderState, OrderEvent> context, String orderId) throws Exception {
                //此处并没有进行持久化操作
                System.out.println("write >> "+orderId);
                MockDB.orders.put(orderId, context.getState());
            }

            @Override
            public StateMachineContext<OrderState, OrderEvent> read(String  orderId) throws Exception {
                //此处直接获取order中的状态，其实并没有进行持久化读取操作
//                return new DefaultStateMachineContext<>(order.getStatus(), null, null, null);
                OrderState orderState=  MockDB.orders.get(orderId);
                return new DefaultStateMachineContext<>(orderState, null, null, null);
            }
        });
    }}
